﻿namespace DimensionsHelper.LanguageService.Symbols;

/// <summary>
///     定义域符号表，需要指定包含此定义域的符号声明。
///     带有定义域的符号类型有：Module，Interface，Class，Enum，Function，EventSection
/// </summary>
/// <param name="domainSymbol">定义域声明符号</param>
public class DomainSymbolTable(ISymbol domainSymbol) : SymbolTable
{
    private readonly Dictionary<string, LabelSymbol> _labels = new(StringComparer.OrdinalIgnoreCase);
    protected override Dictionary<string, ISymbol> Symbols { get; } = new(StringComparer.OrdinalIgnoreCase);

    public override ReadOnlySymbolTable? Parent =>
        // 查找区间符号的父级符号所包含的符号表。
        domainSymbol.ContainingSymbol switch
        {
            // Interface, Class，Enum
            { Kind: SymbolKinds.NamedType } => ((NamedTypeSymbol)domainSymbol).NamedMembers,
            // Module
            { Kind: SymbolKinds.Module } => ((ModuleSymbol)domainSymbol).NamedMembers,
            // Event
            { Kind: SymbolKinds.EventSection } => ((SectionSymbol)domainSymbol).Locals,
            // Metadata Field
            { Kind: SymbolKinds.MetadataField } => ((MetadataFieldSymbol)domainSymbol).FieldSymbols,
            // 不允许声明局部函数，因此，父符号表不会是函数定义的定义域符号表
            _ => null
        };


    public override ISymbol DomainSymbol => domainSymbol;


    /// <summary>
    ///     声明一个行标签符号。
    /// </summary>
    /// <param name="symbol">行标签</param>
    /// <returns>如果符号名已存在，返回<see langword="false" /></returns>
    public bool DeclareLabel(LabelSymbol symbol)
    {
        return _labels.TryAdd(symbol.Name, symbol);
    }


    /// <summary>
    ///     查找指定名称的行标签
    /// </summary>
    /// <param name="name">标签名，不区分大小写</param>
    public LabelSymbol? LookupLabel(string name)
    {
        return _labels.GetValueOrDefault(name);
    }
}